//
// Created by lenovo on 2024/7/20.
//

#ifndef TEYVATSURVIVAL_PHYSICS_RIGIDBODY_RIGIDBODY2D_H
#define TEYVATSURVIVAL_PHYSICS_RIGIDBODY_RIGIDBODY2D_H
#include "../Collision/Collision.h"

namespace Phy::Rigid{
    using namespace Phy::Collision;

    enum class RigidBodyState {
        Static,
        Dynamic,
        Kinematic,
        Sleeping,
        Disabled
    };

    class RigidBody2D {
    public:
        RigidBody2D(Collider* collider, float mass = 1.0f, RigidBodyState state = RigidBodyState::Dynamic)
                : collider(collider), mass(mass), state(state), velocity(0.0f, 0.0f), accumulatedForce(0.0f, 0.0f) {}

        /**
         * @note
         * 此处分为了瞬时力和持续力
         * 比如说
         *  碰撞的时候的冲量
         *  重力，摩擦力等等
         */
        void applyForce(const sf::Vector2f& force) {
            if (state == RigidBodyState::Dynamic) {
                accumulatedForce += force;
            }
        }

        // 瞬时力的应用
        void applyImpulse(const sf::Vector2f& impulse) {
            if (state == RigidBodyState::Dynamic) {
                sf::Vector2f deltaV = impulse / mass;
                velocity += deltaV;
            }
        }

        void update(float deltaTime) {
            if (state == RigidBodyState::Dynamic) {
                Vector2f acceleration = accumulatedForce / mass;
                velocity += acceleration * deltaTime;
                collider->move(velocity * deltaTime);
                accumulatedForce = sf::Vector2f(0.0f, 0.0f); // Reset accumulated force after each update
            } else if (state == RigidBodyState::Kinematic) {
                collider->move(velocity * deltaTime);
            }
        }

        void setVelocity(const sf::Vector2f& vel) {
            if (state == RigidBodyState::Dynamic || state == RigidBodyState::Kinematic) {
                velocity = vel;
            }
        }

        const Vector2f& getVelocity() const {
            return velocity;
        }

        float getMass() const {
            return mass;
        }

        RigidBodyState getState() const {
            return state;
        }

        void setState(RigidBodyState newState) {
            state = newState;
        }

        Collider* getCollider() const {
            return collider;
        }

    public:
        Collider* collider;
        float mass;
        RigidBodyState state;
        sf::Vector2f velocity;
        sf::Vector2f accumulatedForce; // Accumulated force over a frame
    };
}
#endif //TEYVATSURVIVAL_PHYSICS_RIGIDBODY_RIGIDBODY2D_H
